//<SCRIPT>
var allPorts = [];
var excludePaths = 
[
	 "BroadcastDistribution.Destinations"
	,"AccessControl"
	,"ProxyRoutingTable"
	,"WebServerPort"
	,"SplitterSourceList"
	,"LicensePublishers"
	,"Windows Media Live Broadcast Source"
	,"ProxyAlternates"
	,"ServerAlternates"
	,"ContentSubscription"
	,"Multicast.PNAPort"
	,"Multicast.RTSPPort"
];
function initAllPortsList ( configList /*, optional registry path to exclude, exclude 2, etc. */ )
{
	// build path exclusion regex
	for ( var i = 1; i < arguments.length; i++ )
	{
		excludePaths[ excludePaths.length ] = arguments[ i ];
	}
	var sRegExp = ""
	for ( var i = 0; i < excludePaths.length; i++ )
	{
		sRegExp += escRegExMetaChars( excludePaths[ i ] ) + 
					(i < excludePaths.length-1 ? "|" : "");
	}

	var regExpExclPaths = new RegExp( sRegExp, "i" );
	var regExpPort = new RegExp( ".*(Port|PortRange)$", "i" );
	var regExpPortExcept = new RegExp( "transport|support", "i" );
	function _callback ( a, propName, curDepth, curPath )
	{
		if ( typeof( a[ propName ] ) == "object" )
		{
			return;
		}
		// Netscape 4 interperets propnames like "100" as numbers
		if ( typeof( propName ) == "number" )
		{
			return;
		}
		if ( ! propName.bSearch( regExpPort ) )
		{
			return ;
		}
		if ( propName.bSearch( regExpPortExcept ) )
		{
			return ;
		}
		// filter out ports that are used for allowances or that refer to ports
		// on other servers (see excludePaths above)
		if ( curPath.bSearch( regExpExclPaths ) )
			return ;

		allPorts[ curPath ] = a[ propName ];
	}
	enumPropArray( configList, _callback );
}
function findPortConflictName ( lowerPort, upperPort )
{
	// handle case where the lowerPort was in 'PortRange' format: "NNNN-NNNN"
	var aTemp = (""+lowerPort).split( /\s*-\s*/ );
	if ( aTemp && aTemp[ 0 ] && aTemp[ 1 ] )
	{
		upperPort = aTemp[ 1 ];
	}
	else
	{
		upperPort = parseInt( upperPort );
	}
	lowerPort = parseInt( lowerPort );
	if ( isNaN( lowerPort ) || (lowerPort == 0) )
		return "" ;
	if ( isNaN( upperPort ) )
		upperPort = lowerPort ;
	for ( var name in allPorts )
	{
		var port = allPorts[ name ];
		if ( ! name.bSearch( /PortRange/ ) )
		{
			if ( (port == lowerPort) ||
				 (upperPort &&
				  (port >= lowerPort) &&
				  (port <= upperPort)) )
			{
				return name ;
			}
		}
		else
		{

			if ( isPortRangeOverlap( lowerPort, upperPort, port ) )
			{
				return name ;
			}
		}
	}
	return "" ;
}
function isPortRangeOverlap ( lower1, upper1, lower2, upper2 )
{
	// handle case where lower1 is in 'PortRange' format: "NNNN-NNNN"
	var aTemp1 = (""+lower1).split( /\s*-\s*/ );
	if ( aTemp1 && aTemp1[ 0 ] && aTemp1[ 1 ] )
	{
		// handle case where upper1 is in 'PortRange' format: "NNNN-NNNN"
		var aTemp2 = (""+upper1).split( /\s*-\s*/ );
		if ( aTemp2 && aTemp2[ 0 ] && aTemp2[ 1 ] )
		{
			lower1 = parseInt( aTemp1[ 0 ] );
			upper1 = parseInt( aTemp1[ 1 ] );
			lower2 = parseInt( aTemp2[ 0 ] );
			upper2 = parseInt( aTemp2[ 1 ] );
		}
		else
		{
			upper2 = lower2;
			lower2 = upper1;
			lower1 = parseInt( aTemp1[ 0 ] );
			upper1 = parseInt( aTemp1[ 1 ] );
		}
	}
	// handle case where lower2 is in 'PortRange' format: "NNNN-NNNN"
	aTemp1 = (""+lower2).split( /\s*-\s*/ );
	if ( aTemp1 && aTemp1[ 0 ] && aTemp1[ 1 ] )
	{
		lower2 = parseInt( aTemp1[ 0 ] );
		upper2 = parseInt( aTemp1[ 1 ] );
	}
	// assumes both ranges are valid: lowerX <= upperX
	if ( lower1 <= lower2 )
	{
		return (lower2 <= upper1);
	}
	else
	{
		return (lower1 <= upper2);
	}
}
function getConflictErrMsg ( configPathThanConflicts, propName )
{
	var port = allPorts[ configPathThanConflicts ];
	if ( port )
	{
		port = "' (" + port + ").";
	}
	else
	{
		port = "'.";
	}
	return "该 " + propName + " 与'" + configPathThanConflicts + port + " 发生冲突 ";
}
function PortRangeCtrl ( name, minRange, isRequired )
{
	this.m_name = (name ? name : "PortRange");
	this.m_minRange = (minRange != null ? minRange : 0);
	this.m_isRequired = (isRequired != null ? isRequired : true);
	this.m_port1 = this.m_name + "1";
	this.m_port2 = this.m_name + "2";
}
PortRangeCtrl.prototype.fillForm = function ( oForm )
{
	if ( oForm && 
		 oForm[ this.m_name ] && 
		 oForm[ this.m_port1 ] && 
		 oForm[ this.m_port2 ] )
	{
		// split PortRange into lower and upper display fields
		var aTemp = getCtrlValue( oForm[ this.m_name ] ).split( /\s*-\s*/ );
		setCtrlValue( oForm[ this.m_port1 ], (aTemp[0] ? aTemp[0] : ""), true );
		setCtrlValue( oForm[ this.m_port2 ], (aTemp[1] ? aTemp[1] : ""), true );
	}	
}
PortRangeCtrl.prototype.validate = function ( oForm )
{
	if ( oForm && 
		 oForm[ this.m_name ] && 
		 oForm[ this.m_port1 ] && 
		 oForm[ this.m_port2 ] )
	{
		var port1 = getCtrlValue( oForm[ this.m_port1 ] );
		var port2 = getCtrlValue( oForm[ this.m_port2 ] );
		// both pieces missing?
		if ( isBlank( port1 ) && isBlank( port2 ) )
		{
			if ( this.m_isRequired )
			{
				return rejectInput( oForm[ this.m_port1 ], 
					"必须输入端口范围." );
			}
			else
			{
				setCtrlValue( oForm[ this.m_name ], "" );
				return true;
			}
		}
		var err1 = getPortErr( port1 );
		var err2 = getPortErr( port2 );
		// one piece missing?
		if ( isBlank( port1 ) || isBlank( port2 ) )
		{
			// fill in the missing piece
			if ( isBlank( port1 ) && !err2 )
			{
				port1 = Math.max( 0, parseInt( port2, 10 ) - this.m_minRange );
				err1 = getPortErr( port1 );
				if ( ! err1 )
				{
					setCtrlValue( oForm[ this.m_port1 ], port1, true );
				}
			}
			else if ( !err1 )
			{
				port2 = Math.min( 65535, parseInt( port1, 10 ) + this.m_minRange );
				err2 = getPortErr( port2 );
				if ( ! err2 )
				{
					setCtrlValue( oForm[ this.m_port2 ], port2, true );
				}
			}
		}
		if ( err1 )
			return rejectInput( oForm[ this.m_port1 ], err1 );
		if ( err2 )
			return rejectInput( oForm[ this.m_port2 ], err2 );
		port1 = parseInt( port1, 10 );
		port2 = parseInt( port2, 10 );
		if ( port1 > port2 )
		{
			// user must be lesydexic, give em a break
			var tmp = port1;
			port1 = port2;
			port2 = tmp;
		}
		if ( Math.abs(port1 - port2) < this.m_minRange )
		{
			return rejectInput( oForm[ this.m_port1 ], 
				"无效的端口范围. 有效的端口范围必须包含至少 " +
				 (this.m_minRange+1) + " 个端口".pluralize(this.m_minRange+1) + "." );
		}
		// combine into PortRange field
		setCtrlValue( oForm[ this.m_name ], port1 + "-" + port2, true );
		return true ;
	}
}
function getPortErr ( origPort )
{
	port = parseInt( origPort, 10 );
	if ( (port != origPort) ||
		 isNaN( port ) || 
		 (port > 65535) ||
		 (port == 0) )
	{
		return "'" + origPort + "' 是一个无效的端口. 有效的端口数值必须在 1 和 65535之间." ;
	}
	return "";
}
//</SCRIPT>

